import {later} from './later/later'

/**
 * 表演任务
 */
class CronShowTask {
    constructor(index, data) {
        this.index = index
        this.parent_scenic_area = null
        this.scenic_area = null
        this.cron = null
        this.duration = null    // 毫秒
        this.cronObj = null;
        this.timer = null
        this.schedule = null
        this.advance = null   // 毫秒
        this.init(data)
    }

    init(data) {
        const sep = ';';
        let vals = data.split(sep)
        if (vals.length < 3) {
            vals = data.split(',')
        }
        this.cron = vals[0]
        this.duration = parseInt(vals[1]) * 60 * 1000
        this.advance = parseInt(vals[2]) * 60 * 1000
        later.date.localTime()
        this.cronObj = later.parse.cron(this.cron)
        this.schedule = later.schedule(this.cronObj)
    }

    /**
     * 最近演出时间
     */
    calcRecentShowStartTime(showDate) {
        let that = this
        that.scenic_area.recent_show_time ??= {}
        that.scenic_area.recent_show_time[that.index] = showDate
        var recentDate = null
        for (const i in that.scenic_area.recent_show_time) {
            if (recentDate == null) {
                recentDate = that.scenic_area.recent_show_time[i]
            } else {
                if (recentDate.getTime() > that.scenic_area.recent_show_time[i].getTime()) {
                    recentDate = that.scenic_area.recent_show_time[i]
                }
            }
        }
        that.scenic_area.nearest_show_time = recentDate
        that.scenic_area.recent_show_time_str = (1+recentDate.getMonth()) + '月' + recentDate.getDate() + '日'
            + ' ' +  recentDate.getHours() + '时' + recentDate.getMinutes() + '分'
    }

    /**
     * 计算今日演出时间
     */
    calcTodayShowStartTime() {
        let that = this
        let nowDate = new Date();
        // let daySart = new Date(new Date(new Date().toLocaleDateString()).getTime()) 
        let dayEnd = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1)
        that.scenic_area.today_show_time ??= {}
        that.scenic_area.today_show_time[that.index] = that.schedule.next(100, nowDate, dayEnd);
    }

    start() {
        let that = this
        let nowDate = new Date();
        let dayEnd2 = new Date(new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1)
        let preData = that.schedule.prev(1);
        let nextDate = that.schedule.next(1, nowDate, dayEnd2);
        if (nextDate == 0) {
            return
        }
        that.calcTodayShowStartTime()
        // 检查当前是否正在执行
        if (preData != 0 && preData.getTime() + this.duration > nowDate.getTime()) {
            // 开始执行
            that.calcRecentShowStartTime(preData)
            that.executeTask(nowDate.getTime(), preData.getTime(), preData.getTime() + this.duration)
        } else {
            // 计划下一次执行
            that.calcRecentShowStartTime(nextDate)
            that.prepareNextTask(nextDate.getTime(), nowDate.getTime())
        }
    }

    stop() {
        var that = this;
        if (that.timer == null) {
            return
        }
        that.scenic_area.right_badge = null
        that.parent_scenic_area.hidePoi(that.scenic_area)
        clearTimeout(that.timer);
        that.timer = null
    }

    /**
     * 执行任务
     * @param {int} warnStartTime 提醒开始时间
     * @param {int} showStartTime 表演开始时间
     * @param {int} showEndTime 表演结束时间
     */
    executeTask(warnStartTime, showStartTime, showEndTime) {
        var that = this;
        if (that.timer != null) {
            clearTimeout(that.timer)
            that.timer = null
        }
        // 显示
        that.scenic_area.right_badge = '演'
        that.parent_scenic_area.showPoi(that.scenic_area)
        let intavalTime = showEndTime - warnStartTime;
        console.log('start date: ' + new Date())
        console.log('executeTask intavalTime: ' + intavalTime)
        that.timer = setTimeout(function() {
            that.scenic_area.right_badge = null
            that.parent_scenic_area.hidePoi(that.scenic_area)
            // 计划下一次
            let nowDate = new Date();
            // let daySart = new Date(new Date(new Date().toLocaleDateString()).getTime())
            let dayEnd2 = new Date(new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1)
            // let preData = that.schedule.prev(1, daySart, nowDate);
            let nextDate = that.schedule.next(1, nowDate, dayEnd2);
            console.log(nextDate)
            that.calcRecentShowStartTime(nextDate)
            console.log('end date: ' + nowDate)
            that.prepareNextTask(nextDate.getTime(), nowDate.getTime())
        }, Math.max(0, intavalTime))
    }

    /**
     * 准备下一次任务
     */
    prepareNextTask(nextTime, nowTime) {
        var that = this;
        if (that.timer != null) {
            clearTimeout(that.timer)
            that.timer = null
        }
        
        let intervalTime = nextTime - nowTime - that.advance
        console.log('prepareNextTask intervalTime: ' + intervalTime)
        that.timer = setTimeout(function() {
            that.executeTask(Math.max(nowTime, nextTime - that.advance), nextTime, nextTime + that.duration)
        }, Math.max(0, nextTime - nowTime - that.advance))
    }

    
}

class ScenicCronTask {
    constructor() {
        this.parent_scenic_area = null
        this.scenic_area = null
        this.scenicid = null
        this.task_type = null
        this.grade = null
        this.detail = null
        this.cron_task = []
    }

    init(data) {
        this.scenicid = data['scenic_area']
        this.task_type = data['task_type']
        this.grade = data['grade']
        this.detail = data['detail']
        this.cron_task = []
        if (data['cron_task'] != null && data['cron_task'] != '') {
            let cron_task_data = data['cron_task'].split("|")
            for (let i=0; i<cron_task_data.length; ++i) {
                this.cron_task.push(new CronShowTask(i, cron_task_data[i]))
            }
        }
    }

    /**
     * 启动任务
     */
    start() {
        let that = this
        for (let iTask=0; iTask<that.cron_task.length; ++iTask) {
            that.cron_task[iTask].parent_scenic_area = that.parent_scenic_area
            that.cron_task[iTask].scenic_area = that.scenic_area
            that.cron_task[iTask].start()
        }
    }

    /**
     * 停止任务
     */
    stop() {
        let that = this
        for (let iTask=0; iTask<that.cron_task.length; ++iTask) {
            that.cron_task[iTask].stop()
        }
    }
}

class ScenicCronTaskMng {
    constructor() {
        this.parent_scenic_area = null
        this.scenicid2task = {}
        this.scenicid2scenictype = {}
        this.scenicid2scenic = {}
        this.running = false;
    }

    init(parent_scenic_area) {
        let that = this
        that.parent_scenic_area = parent_scenic_area
        global.wxRequest.getCronTaskList(that.parent_scenic_area, function(data) {
            that.scenicid2task = {}
            for (let i=0; i<data.length; ++i) {
                let _item = new ScenicCronTask()
                _item.init(data[i])
                that.scenicid2task[_item.scenicid] = _item
            }
            let children_scenic_area_type = parent_scenic_area.children_scenic_area_type
            that.scenicid2scenic = {};
            that.scenicid2scenictype = {};
            for (let t=0; t<children_scenic_area_type.length; ++t) {
                that.scenicid2scenictype[children_scenic_area_type[t].id] = children_scenic_area_type[t]
                for (let s=0; s<children_scenic_area_type[t].items.length; ++s) {
                    let item = children_scenic_area_type[t].items[s]
                    that.scenicid2scenic[item.id] = item;
                }
            }
            let unloaded = []
            for (const scenicid in that.scenicid2task) {
                if (!that.scenicid2scenic.hasOwnProperty(scenicid)) {
                    unloaded.push(scenicid)
                }
            }
        
            if (unloaded.length == 0) {
                that.start()
            } else {
                global.wxRequest.postScenicList(unloaded, function(data) {
                    var view = require('./view')
                    for (let i=0; i<data.length; ++i) {
                        let scenic = new view.ScenicArea(data[i])
                        if (!that.scenicid2scenictype.hasOwnProperty(scenic.scenic_area_type)) {
                            continue
                        }
                        if (that.scenicid2scenic.hasOwnProperty(scenic.id)) {
                            continue
                        }
                        that.scenicid2scenictype[scenic.scenic_area_type].items.push(scenic)
                        that.scenicid2scenic[scenic.id] = scenic;
                    } 
                    that.start()
                })
            }
        });
    }

    start() {
        let that = this
        let hasTask = false
        for (const scenicid in that.scenicid2task) {
            that.scenicid2task[scenicid].parent_scenic_area = that.parent_scenic_area
            that.scenicid2task[scenicid].scenic_area = that.scenicid2scenic[scenicid]
            that.scenicid2task[scenicid].start()
            hasTask = true
        }
        if (hasTask) {
            that.parent_scenic_area.page.setData({
                scenicShowControl: true
            })
            this.running = true;
        }
    }

    stop() {
        let that = this
        for (const scenicid in that.scenicid2task) {
            that.scenicid2task[scenicid].stop()
        }
        this.running = false;
    }
}

export {ScenicCronTaskMng}